home *** CD-ROM | disk | FTP | other *** search
/ Gekikoh Dennoh Club 5 / Gekikoh Dennoh Club Vol. 5 (Japan).7z / Gekikoh Dennoh Club Vol. 5 (Japan) (Track 01).bin / internet / xip / iijppp.lzh / src / lqr.c < prev    next >
C/C++ Source or Header  |  1994-10-11  |  6KB  |  258 lines

  1. /*
  2.  *          PPP Line Quality Monitoring (LQM) Module
  3.  *
  4.  *        Written by Toshiharu OHNO (tony-o@iij.ad.jp)
  5.  *
  6.  *   Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
  7.  *
  8.  * Redistribution and use in source and binary forms are permitted
  9.  * provided that the above copyright notice and this paragraph are
  10.  * duplicated in all such forms and that any documentation,
  11.  * advertising materials, and other materials related to such
  12.  * distribution and use acknowledge that the software was developed
  13.  * by the Internet Initiative Japan, Inc.  The name of the
  14.  * IIJ may not be used to endorse or promote products derived
  15.  * from this software without specific prior written permission.
  16.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  17.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  18.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  19.  *
  20.  *    o LQR based on RFC1333
  21.  *
  22.  * TODO:
  23.  *    o LQM policy
  24.  *    o Allow user to configure LQM method and interval.
  25.  */
  26. #include "fsm.h"
  27. #include "lcpproto.h"
  28. #include "lqr.h"
  29. #include "hdlc.h"
  30. #include "lcp.h"
  31. #include "vars.h"
  32.  
  33. struct pppTimer LqrTimer;
  34.  
  35. static u_long lastpeerin = (u_long)-1;
  36.  
  37. static int lqmmethod;
  38. static int echoseq;
  39. static int gotseq;
  40. static int lqrsendcnt;
  41.  
  42. struct echolqr {
  43.   u_long magic;
  44.   u_long signature;
  45.   u_long sequence;
  46. };
  47.  
  48. #define    SIGNATURE  0x594e4f54
  49.  
  50. static void
  51. SendEchoReq()
  52. {
  53.   struct fsm *fp = &LcpFsm;
  54.   struct echolqr *lqr, lqrdata;
  55.  
  56.   if (fp->state == ST_OPENED) {
  57.     lqr = &lqrdata;
  58.     lqr->magic = htonl(LcpInfo.want_magic);
  59.     lqr->signature = htonl(SIGNATURE);
  60.     LogPrintf(LOG_LQM, "Send echo LQR [%d]\n", echoseq);
  61.     lqr->sequence = htonl(echoseq++);
  62.     FsmOutput(fp, CODE_ECHOREQ, fp->reqid++,
  63.           (u_char *)lqr, sizeof(struct echolqr));
  64.   }
  65. }
  66.  
  67. void
  68. RecvEchoLqr(bp)
  69. struct mbuf *bp;
  70. {
  71.   struct echolqr *lqr;
  72.   u_long seq;
  73.  
  74.   if (plength(bp) == sizeof(struct echolqr)) {
  75.     lqr = (struct echolqr *)MBUF_CTOP(bp);
  76.     if (htonl(lqr->signature) == SIGNATURE) {
  77.       seq = ntohl(lqr->sequence);
  78.       LogPrintf(LOG_LQM, "Got echo LQR [%d]\n", ntohl(lqr->sequence));
  79.       gotseq = seq;
  80.     }
  81.   }
  82. }
  83.  
  84. void
  85. LqrChangeOrder(src, dst)
  86. struct lqrdata *src, *dst;
  87. {
  88.   u_long *sp, *dp;
  89.   int n;
  90.  
  91.   sp = (u_long *)src; dp = (u_long *)dst;
  92.   for (n = 0; n < sizeof(struct lqrdata)/sizeof(u_long); n++)
  93.     *dp++ = ntohl(*sp++);
  94. }
  95.  
  96. static void
  97. SendLqrReport()
  98. {
  99.   struct mbuf *bp;
  100.  
  101.   StopTimer(&LqrTimer);
  102.  
  103.   if (lqmmethod & LQM_LQR) {
  104.     if (lqrsendcnt > 5) {
  105.       /*
  106.        * XXX: Should implement LQM strategy
  107.        */
  108.       LogPrintf(LOG_PHASE, "** Too many ECHO packets are lost. **\n");
  109.       LcpClose();
  110.       Cleanup(EX_ERRDEAD);
  111.     } else {
  112.       bp = mballoc(sizeof(struct lqrdata), MB_LQR);
  113.       HdlcOutput(PRI_URGENT, PROTO_LQR, bp);
  114.       lqrsendcnt++;
  115.     }
  116.   } else if (lqmmethod & LQM_ECHO) {
  117.     if (echoseq - gotseq > 5) {
  118.       LogPrintf(LOG_PHASE, "** Too many ECHO packets are lost. **\n");
  119.       LcpClose();
  120.       Cleanup(EX_ERRDEAD);
  121.     } else
  122.       SendEchoReq();
  123.   }
  124.  
  125.   if (lqmmethod && Enabled(ConfLqr))
  126.     StartTimer(&LqrTimer);
  127. }
  128.  
  129. void
  130. LqrInput(struct mbuf *bp)
  131. {
  132.   int len;
  133.   u_char *cp;
  134.   struct lqrdata *lqr;
  135.  
  136.   len = plength(bp);
  137.   if (len != sizeof(struct lqrdata)) {
  138.     pfree(bp);
  139.     return;
  140.   }
  141.  
  142.   if (!Acceptable(ConfLqr)) {
  143.     bp->offset -= 2;
  144.     bp->cnt += 2;
  145.  
  146.     cp = MBUF_CTOP(bp);
  147.     LcpSendProtoRej(cp, bp->cnt);
  148.   } else {
  149.     cp = MBUF_CTOP(bp);
  150.     lqr = (struct lqrdata *)cp;
  151.     if (ntohl(lqr->MagicNumber) != LcpInfo.his_magic) {
  152. #ifdef notdef
  153. logprintf("*** magic %x != expecting %x\n", ntohl(lqr->MagicNumber), LcpInfo.his_magic);
  154. #endif
  155.       pfree(bp);
  156.       return;
  157.     }
  158.  
  159.     /*
  160.      * Convert byte order and save into our strage
  161.      */
  162.     LqrChangeOrder(lqr, &HisLqrData);
  163.     LqrDump("LqrInput", &HisLqrData);
  164.     lqrsendcnt = 0;    /* we have received LQR from peer */
  165.  
  166.     /*
  167.      *  Generate LQR responce to peer, if
  168.      *    i) We are not running LQR timer.
  169.      *   ii) Two successive LQR's PeerInLQRs are same.
  170.      */
  171.     if (LqrTimer.load == 0 || lastpeerin == HisLqrData.PeerInLQRs) {
  172.       lqmmethod |= LQM_LQR;
  173.       SendLqrReport();
  174.     }
  175.     lastpeerin = HisLqrData.PeerInLQRs;
  176.   }
  177.   pfree(bp);
  178. }
  179.  
  180. /*
  181.  *  When LCP is reached to opened state, We'll start LQM activity.
  182.  */
  183. void
  184. StartLqm()
  185. {
  186.   struct lcpstate *lcp = &LcpInfo;
  187.   int period;
  188.  
  189.   lqmmethod = LQM_ECHO;
  190.   if (Enabled(ConfLqr))
  191.     lqmmethod |= LQM_LQR;
  192.   StopTimer(&LqrTimer);
  193.   LogPrintf(LOG_LQM, "LQM method = %d\n", lqmmethod);
  194.  
  195.   if (lcp->his_lqrperiod || lcp->want_lqrperiod) {
  196.     /*
  197.      *  We need to run timer. Let's figure out period.
  198.      */
  199.     period = lcp->his_lqrperiod ? lcp->his_lqrperiod : lcp->want_lqrperiod;
  200.     StopTimer(&LqrTimer);
  201.     LqrTimer.state = TIMER_STOPPED;
  202.     LqrTimer.load = period * SECTICKS / 100;
  203.     LqrTimer.func = SendLqrReport;
  204.     SendLqrReport();
  205.     StartTimer(&LqrTimer);
  206.     LogPrintf(LOG_LQM, "Will send LQR every %d.%d secs\n",
  207.           period/100, period % 100);
  208.   } else {
  209.     LogPrintf(LOG_LQM, "LQR is not activated.\n");
  210.   }
  211. }
  212.  
  213. void
  214. StopLqr(method)
  215. int method;
  216. {
  217.   LogPrintf(LOG_LQM, "StopLqr method = %x\n", method);
  218.  
  219.   if (method == LQM_LQR)
  220.     LogPrintf(LOG_LQM, "Stop sending LQR, Use LCP ECHO instead.\n");
  221.   if (method == LQM_ECHO)
  222.     LogPrintf(LOG_LQM, "Stop sending LCP ECHO.\n");
  223.   lqmmethod &= ~method;
  224.   if (lqmmethod)
  225.     SendLqrReport();
  226.   else
  227.     StopTimer(&LqrTimer);
  228. }
  229.  
  230. void
  231. LqrDump(message, lqr)
  232. char *message;
  233. struct lqrdata *lqr;
  234. {
  235.   if (loglevel >= LOG_LQM) {
  236.     LogTimeStamp();
  237.     logprintf("%s:\n", message);
  238.     LogTimeStamp();
  239.     logprintf("  Magic:          %08x   LastOutLQRs:    %08x\n",
  240.     lqr->MagicNumber, lqr->LastOutLQRs);
  241.     LogTimeStamp();
  242.     logprintf("  LastOutPackets: %08x   LastOutOctets:  %08x\n",
  243.     lqr->LastOutPackets, lqr->LastOutOctets);
  244.     LogTimeStamp();
  245.     logprintf("  PeerInLQRs:     %08x   PeerInPackets:  %08x\n",
  246.     lqr->PeerInLQRs, lqr->PeerInPackets);
  247.     LogTimeStamp();
  248.     logprintf("  PeerInDiscards: %08x   PeerInErrors:   %08x\n",
  249.     lqr->PeerInDiscards, lqr->PeerInErrors);
  250.     LogTimeStamp();
  251.     logprintf("  PeerInOctets:   %08x   PeerOutLQRs:    %08x\n",
  252.     lqr->PeerInOctets, lqr->PeerOutLQRs);
  253.     LogTimeStamp();
  254.     logprintf("  PeerOutPackets: %08x   PeerOutOctets:  %08x\n",
  255.     lqr->PeerOutPackets, lqr->PeerOutOctets);
  256.   }
  257. }
  258.